
const { logger } = require('../middleware/error.js');



function authenticateToken (req, res, next) {
 // 从请求头中获取token
 const authHeader = req.headers['authorization'];
 const token = authHeader && authHeader.split(' ')[1];
 if (token == null) return res.sendStatus(401); // 如果没有token，返回401 Unauthorized
 // 在这里验证token的有效性，例如检查token是否在数据库中，是否过期等
 // 假设我们有一个函数checkTokenValidity来验证token
 if (!checkTokenValidity(token)) return res.sendStatus(403); // 如果token无效，返回403 Forbidden
 // 如果token有效，将用户信息附加到请求对象上，以便后续处理使用
 req.user = getUserFromToken(token); // 假设我们有一个函数getUserFromToken来从token中获取用户信息
 next(); // 继续处理请求
}

function errFn (res, err) {
 logger.error(`url: ${res.req.url};body: ${JSON.stringify(res.req.body)};Error in TryCatch :${err}`)
 res.status(500).send('服务器内部错误');
}

/**
 * 捕获错误异常, 并记录日志  主要用于路由中逻辑较多的情况处理
 * 封装的原因：Node.js 14 以后的版本中，对于异步任务中抛出的未捕获异常的处理变得更加严格，可能会导致进程直接退出
 * @param {*} res 响应对象
 * @param {*} fn 路由执行函数
 * @param {*} cb 回调函数 非必填，可以不传递
 */
async function TryCatch (res, fn, cb) {
 // node官方文档并不推荐将 uncaughtException 作为常规的错误处理机制，
 // 因为它可能会导致应用处于不稳定的状态，并且可能会掩盖一些潜在的问题。
 //  process.on('uncaughtException', (error) => {
 //   console.error('Uncaught Exception:', error);
 // });
 //! unhandledRejection 是 Node.js 中的一个事件，它专门用于处理那些未被捕获的 Promise 拒绝（rejection）情况
 process.on('unhandledRejection', (err, promise) => {
  console.error('Unhandled Rejection:', err);
  // 你可以在这里添加日志记录、告警等
  errFn(res, err)
 });
 new Promise(async (resolve, reject) => {
  fn()
 }).catch(err => {
  errFn(res, err)
 })
}

/**
 * 上面的同步方法
 * @param {*} params 
 */
async function TryCatchSync (res, fn, cb) {
 try {
  await fn()
  cb && cb()
 } catch (error) {
  errFn(res, error)
 }
}

// 封装一个检查必填参数的中间件, 检查请求体中的必填参数,支持post和get请求的参数
const CheckRequiredParams = (requiredParams) => {
 return (req, res, next) => {
  let missingParams = []
  if (req.method === 'POST') {
   missingParams = requiredParams.filter(param => !req.body[param]);
  } else if (req.method === 'GET') {
   missingParams = requiredParams.filter(param => !req.query[param]);
  }
  if (missingParams.length > 0) {
   return res.status(400).send(`${missingParams.join(', ')} 参数是必填的`);
  }
  next();
 };
};


module.exports = {
 TryCatch,
 TryCatchSync,
 CheckRequiredParams,
 authenticateToken
}